×
☰ See All Chapters

Java Method Reference

Java 8 lambda expressions avoids creating objects for functional interface. If in an application if there is already some method in some class, which we feel, is a perfect implementation of functional method of functional interface, wouldn’t be nice if we could refer this existing methods instead of using a lambda expression? This is exactly what we can do using method references.

Before Java 1.8:

package com.java4coding;

 

interface PrintHello {

        public void print();

}

 

class PrintHelloImpl implements PrintHello {

        public void print() {

                System.out.println("Hello");

        }

}

 

public class Demo {

        public static void main(String[] args) {

                PrintHello printHello = new PrintHelloImpl();

                printHello.print();

        }

}

With Java 1.8 lambda expression:

package com.java4coding;

 

interface PrintHello {

        public void print();

}

 

public class LambdaExpressionDemo {

 

        public static void main(String[] args) {

                PrintHello printHello = () -> {System.out.println("Hello");};

                printHello.print();

        }

}

With Java 1.8 method references:

package com.java4coding;

 

interface PrintHello {

        public void print();

}

 

class SayHello {

        public void sayHello() {

                System.out.println("Hello");

        }

}

public class Demo {

 

        public static void main(String[] args) {

                SayHello sayHello = new SayHello();

                PrintHello printHello = sayHello::sayHello;

                printHello.print();

        }

}

Types of Method References

There are following types of method references in java:

  1. Reference to a static method. 

  2. Reference to an instance method. 

  3. Reference to a constructor. 

Reference to a Static Method – Class::staticMethodName

Example1:

package com.java4coding;

 

interface PrintHello {

        public void print();

}

 

class SayHello {

        public static void sayHello() {

                System.out.println("Hello");

        }

}

public class Demo {

 

        public static void main(String[] args) {

                SayHello sayHello = new SayHello();

                PrintHello printHello = SayHello::sayHello;

                printHello.print();

        }

}

Example2:

Java 1.8

Java 1.7

package com.java4coding;

class SayHello {

        public static void sayHello() {

                System.out.println("Hello");

        }

}

public class Demo {

        public static void main(String[] args) {

                Thread thread  = new Thread(SayHello::sayHello);

                thread.start();

        }

}

 

package com.java4coding;

class ThreadImpl implements Runnable {

        public void run() {

                System.out.println("Hello");

        }

}

public class Demo {

        public static void main(String[] args) {

                Thread thread  = new Thread(new ThreadImpl());

                thread.start();

        }

}

 

 

 

In the above code we can observe that sayHello() method matches the run method of Runnable interface in return type and parameter list. We felt that, the code inside sayHello() method as the desirable code as when we implement Runnable interface. Thus instead of creating a new class and implementing the Runnable interface we used method reference.

Reference to an Instance Method - ClassInstance::instanceMethodName

Example1:

package com.java4coding;

 

interface PrintHello {

        public void print();

}

 

class SayHello {

        public void sayHello() {

                System.out.println("Hello");

        }

}

public class Demo {

 

        public static void main(String[] args) {

                SayHello sayHello = new SayHello();

                PrintHello printHello = sayHello::sayHello;

                printHello.print();

        }

}

Example2:

Java 1.8

Java 1.7

package com.java4coding;

class SayHello {

        public void sayHello() {

                System.out.println("Hello");

        }

}

public class Demo {

        public static void main(String[] args) {

                Thread thread  = new Thread(new SayHello()::sayHello);

                thread.start();

        }

}

 

package com.java4coding;

class ThreadImpl implements Runnable {

        public void run() {

                System.out.println("Hello");

        }

}

public class Demo {

        public static void main(String[] args) {

                Thread thread  = new Thread(new ThreadImpl());

                thread.start();

        }

}

 

Reference to a Constructor - Class::new

package com.java4coding;

 

class Employee {

        String name ;

        Employee (String name) {

                this.name  = name;

        }

}

 

interface GenerateEmployee {

        Employee getEmployee (String name);

}

public class Demo {

 

        public static void main(String[] args) {

                GenerateEmployee generateEmployee = Employee::new;

                Employee employee =  generateEmployee.getEmployee("Manu Manjunatha");

        }

}

In the above GenerateEmployee functional interface we have functional method getEmployee(), this method will return Employee object and has one String parameter. When Employee class constructor is invoked it returns Employee object and this constructor also has one String parameter, so we can just refer the Employee class constructor to GenerateEmployee functional interface.

 


All Chapters
Author